\chapter{项目特色}
本章节为饿了么项目的特色和创新。

\section{程序安全}
本章节为饿了么项目的安全性升级。将对项目三以及项目四所搭建的Vue +
SpringBoot项目进行安全性的提升。
\subsection{需求分析}
\subsubsection{简介}
本章节为饿了么项目的安全性升级，将对项目三以及项目四所搭建的Vue +
SpringBoot项目进行安全性的提升。
\subsubsection{背景}
程序的安全是项目开发时需要着重考虑的地方。攻击者有可能会从虚假的前端平台注入代码，以对后端数据库中的数据进行篡改；用户隐私信息如：电话号码、登录密码等，通过接口对参数进行明文传输，这使得用户的隐私信息被直接暴露；攻击者可能使用XSS攻击和SQL注入攻击；后端对前端提交的数据和身份并不检验, 导致可能有伪造的前端提交恶意数据，可能修改他人送餐地址，或者修改订单金额等;数据库可能受未经授权的访问和泄露。
我们便将目光聚焦于上面提到的安全问题。
\subsubsection{约束}
结合上文中给关于项目功能方面的要求，本项目应该具有以下约束：
\begin{itemize}
    \item 数据库使用MySQL数据库
    \item 后端使用项目四的后端，前端使用项目三的前端
\end{itemize}


\subsection{安全性需求}
总的来说，需求可以归为数据合法性检查以及数据传输加密：
\begin{itemize}
    \item[$\bullet$] 数据合法性检查：检查用户输入的数据（注册手机号）的合法性，防止输入非法字符串；
    \item[$\bullet$] 数据传输加密：前端将需要传输的数据加密，后端接收到数据后进行解密，且加解密过程安全可靠。
    \item[$\bullet$] 数据库数据加密。
    \item[$\bullet$] XSS攻击和SQL注入攻击
   
    (a) XSS攻击即跨站脚本攻击，是一种HTML注入攻击，其核心思想为在HTML页面中写入恶意代码，使得浏览器访问后端服务器时，由于服务器对浏览器的信任，执行恶意代码从而攻击目标。
    
    (b) SQL注入攻击与XSS攻击相似，只不过代码由XSS常见的script脚本变为了SQL语句。SQL语句被传输到服务器后，在服务器与数据库交互的过程中可能会被执行，从而破坏数据。
    \item[$\bullet$] 权限管理，防止CSRF：原服务器可以通过键入请求，在未登录状态下就请求获取用户订单、购物车等个人信息，需要实现对未登录状态下请求权限的管理；商家系统同理。
  \end{itemize}


\subsection{安全性设计}
\subsubsection{正则表达式}
正则表达式是对字符串操作的一种逻辑公式，就是用事先定义好的一些特定字符及这些特定字符的组合，组成一个“规则字符串”，这个“规则字符串”用来表达对字符串的一种过滤逻辑。
正则表达式是一种文本模式，该模式描述在搜索文本时要匹配的一个或多个字符串。

标准的中国大陆移动手机号形式（不带区号）为十一位数字构成，其中首位数字为1，第二位数字为3-9其中的一位，其余位数字无要求。因此，手机号匹配模式为：

\begin{lstlisting}
var pattern = /^1[3456789]\d{9}$/;
\end{lstlisting}

使用此模式对用户输入的手机号进行匹配，只有通过匹配的字符串才能作为用户名，否则被拒绝。

\subsubsection{RSA非对称加密}
RSA非对称加密是一种基于公钥密码学的加密方法。公钥密码学的核心思想是：
\begin{itemize}
  \item[$\bullet$] 每个节点都有自己公钥publicKey和私钥privateKey（secretKey），公钥和私钥一一对应，形成了公钥-私钥对；
  \item[$\bullet$] 其中公钥是公开的，每个节点都知道其他节点的公钥；
  \item[$\bullet$] 私钥是私密的，只有本节点才知道自己的私钥；
  \item[$\bullet$] 用某一把公钥加密的数据，只能用对应的私钥才能解密。
\end{itemize}

节点A若要向节点B传输数据，则A需要用B的公钥进行加密，并把加密后的密文发送给B。节点B收到密文后再用自己的私钥进行解密。
由于公钥-私钥对应的唯一性，因此由B的公钥加密的数据只能由B解密，其他节点即使可以截获数据也无法解密密文内容。

\begin{figure}[htbp]
\centering
\includegraphics[width=0.9\textwidth]{figures/RSA}
\caption{RSA非对称加密过程}\label{fig:rsa}
%\vspace{\baselineskip} 
\end{figure}

以前端向后端发送登录请求为例，POST请求中包括了用户的用户名和密码两个参数，其中密码需要被加密。

前端使用publicKey加密data：

\begin{lstlisting}
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(this.PublicKey)  // 放入公钥
  let passwordAfterEncrypt = encryptor.encrypt(this.password)  // 加密密码
\end{lstlisting}

后端收到密文后使用privateKey解密，并把解密后的数据传递给Service层:

\begin{lstlisting}
  public String rsa_endjiami(String publicKeyBase64,String mingwen) {
    RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), null, publicKeyBase64);  // 放入公钥来生成对象
    String miwen = rsa.encryptBase64(mingwen, KeyType.PublicKey);
    return miwen;
  }
\end{lstlisting}

\subsubsection{防止XSS攻击和SQL注入攻击}
为防止以上两种攻击，最好在HTTP请求传入时使用过滤器对请求报文进行处理。 本项目实现了XSSUtil， 定义方法对字符串进行处理， 清除违规关键字。 实现XSSRequestWrapper， 继承HttpServletReqestWrapper，对HttpServletRequest进行包装，实现对HTTP请求内参数的修改。

\subsubsection{使用Token令牌验证用户身份}
(a) Token令牌为服务器生成的一串加密字符，作为客户端进行请求的
“令牌”。当用户第一次登录成功后，服务器生成一个令牌返回给客户端，客户端会存储令牌，并在每次请求时携带令牌。

(b) Token具有随机性、不可预测性、无状态等特点，并且完全由应用管理。Token可以有效地避免CSRF跨站请求伪造漏洞。

(c) 实现了TokenUtils工具类用于生成JWT的。它提供了一个方法来创建token，这些token可以用于身份验证和信息传递。后端实现了Spring框架的拦截器JwtInterceptor，用于在处理HTTP请求之前验证JWT token的有效性。

用户密码加签验证 token代码如下：
\begin{lstlisting}
  // 用户密码加签验证 token
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
            try {
                jwtVerifier.verify(token);
            } catch (JWTVerificationException e) {
                setResponse(httpServletResponse, Constants.CODE_401, "没有token，重新登陆");
                return false;
            }
\end{lstlisting}

\subsubsection{限制无登录状态下的请求权限}
(a) 在实现Token的基础上， 实现InterceptorConfig配置类， 每次收
到HTTP请求时都会验证用户的登陆状态。若取得Token，证明用户未登录，则禁止用户访问如订单、支付、我的信息等业务，可以防止伪造请求访问，保护用户的信息不泄露。

(b)放行无登录状态即可发起的请求。
\begin{lstlisting}
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
      registry.addInterceptor(jwtInterceptor)
              .addPathPatterns("/**")    //拦截所有请求 通过判断token是否合法来决定是否登陆
              .excludePathPatterns("/users/authenticate","/users/{userId}","/users/key/{userId}","/users","/businesses","/businesses/authenticate","/businesses/authenticate","/businesses/{businessPassId}","/businesses/key/{businessPassId}"); //放行接口
  }
\end{lstlisting}
\subsubsection{AES对称加密}
AES（Advanced Encryption Standard）是一种对称加密算法，使用相同的密钥进行数据的加密和解密，支持128位、192位和256位的密钥长度，具有很高的安全性和较快的加密速度，适用于大量数据的加密。
实现了AESUtils工具类，提供了使用AES算法进行加密和解密的方法，支持不同的加解密模式。

以用户地址的存取为例：

存入数据库时加密：

deliveryAddress.setAddress(AESUtils.encrypt(deliveryAddress.getAddress(), key));//AES加密

取出数据库时解密：

temp.setAddress(AESUtils.decrypt(temp.getAddress(), key));//AES解密

\subsubsection{MD5加密}
(a) MD5（Message-Digest Algorithm 5）则是一种哈希函数，主要用于生成数据的摘要，以确保数据的完整性和一致性

(b) 为避免md5密文被暴力破解，采用userId和password明文拼接的方式并重复进行四次md5加密，将加密的密文存进数据库

加密方法代码如下：
\begin{lstlisting}
  public String md5jiami(String yuan,String adition) {
    String md5miwen=DigestUtils.md5DigestAsHex((yuan + adition).getBytes());//md5加密
    md5miwen=DigestUtils.md5DigestAsHex((md5miwen + adition).getBytes());//二次加密
    md5miwen=DigestUtils.md5DigestAsHex((md5miwen + adition).getBytes());//三次加密
    return md5miwen;
}
\end{lstlisting}

\section{智能AI客服}
基于“饿了么”项目三的前端和项目四的后端继续开发，在已经完成的“饿了么”项目中增加“AI”新模块。 

下面分析详细功能需求： 

用户可以在主页或者个人中心与AI沟通，通过AI得到更加个性化或者更加合理的饮食建议。
方便用户选择适合自己的菜品进行下单。

\subsection{项目设计}
\subsubsection{后端接口设计}
getGPTResponse 接受GPT的消息 
\subsubsection{实现原理}
调用通译千问的开源API

（1）设置API密钥。

（2）创建文本生成对象和消息管理器。

（3）添加系统和用户消息到消息管理器。

（4）构建包含模型、消息和其他参数的请求。

（5）调用文本生成API。

（6）检查生成结果，提取并返回生成的文本或默认提示。

\subsection{项目成果展示}
点击底部菜单栏“小饿”即可进入AI智能客服页面，如图所示。 

图为与智能AI客服小饿对话情景 
\begin{figure}[htbp]
          \centering
          \includegraphics[width=1\textwidth]{AI}
          \caption{与AI对话}\label{fig:AI}
          \vspace{\baselineskip}
          \end{figure}
\section{消费数据可视化展示 }
基于“饿了么”项目三的前端和项目四的后端继续开发，在已经完成的“饿 
了么”项目中增加“消费数据可视化”新模块。用户可以在钱包—记录里查看过去一周的每日消费总额折线图，方便用户对自己的消费进行观测和管控。 
\subsection{项目设计}
\subsubsection{后端接口设计 }
• listWeeklyTotalById 返回 List<DailyTotal> 
\subsubsection{实现原理}
通过使用 MyBatis 的注解 @Select 来声明一个 SQL 查询： 
SQL 查询语句中的 select 子句选择了两个列： date(payDate) 和 
sum(orderTotal)，分别表示日期和订单总金额的求和，from 子句指定 
了数据表 orders，并通过 where 子句添加了两个筛选条件： 

 userId = \#userId：筛选出具有指定用户ID的订单。 
 \begin{lstlisting}
 STR TO DATE (payDate, \’\%Y-\%m-\%d’) between 

DATE SUB(STR TO DATE(\#currentDate, ’\%Y-\%m-\%d’), 
INTERVAL 1 WEEK) and STR TO DATE(\#currentDate, 
’\%Y-\%m-\%d’)/
\end{lstlisting}
筛选出支付日期在一周之内的订单。 

• group by 子句按照日期 (date(payDate)) 对结果进行分组。 

• order by 子句按照日期 (date(payDate)) 升序排列结果。 

总的来说，这个方法的作用是从名为 orders 的数据表中选择指定用户在 
过去一周内的订单支付日期和订单总金额，然后按日期升序排列，最终 
将结果映射为 List<DailyTotal> 类型的对象列表。这个查询通常用于 
生成一周内的订单汇总数据。 

\subsubsection{项目测试}
listWeeklyTotalById 

• URL:localhost:8080/elm/OrdersController/ 

listWeeklyTotalById?userId=11111111111 

上述URL测试后端在用户名存在时能否返回正确信息。 收到 
的HTTP响应中确实装载了对应正确信息，测试通过。 

\subsubsection{项目成果展示}
在“我的钱包”页面点击“记录”即可进入“消费记录”页面，如图所示。 
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{consume}
  \caption{消费记录展示}\label{fig:consume}
  \vspace{\baselineskip}
  \end{figure}


\section{评价系统 }
本项目为《软件工程综合实践》的创新项目，基于“饿了么”项目三的前端和项目四的后端继续开发，增加“支付订单”与“订单评价”新模块。
\subsection{需求分析}
\subsubsection{简介}
用户创建订单后可以对订单进行支付，在订单界面可以查看自己的未支付订单和已支付订单，对于已支付的订单可以进行评分。
\subsubsection{功能性需求}
(1) 订单支付状态管理：系统应能够追踪每个订单的支付状态，区分未支付和已支付的订单。

(2) 评价入口：在订单界面，对于已支付的订单，系统应提供一个明显的入口供用户进行评价。

(3)评价内容：用户应能够对订单提供文字评论。

(4)评价提交：用户完成评价后，系统应允许用户提交评价内容。

(5)评价存储：系统应永久存储用户的评价内容，包括评分和评论文本。

(6)评价展示：系统应能够在相应的商家页面展示用户的评价。
\subsection{约束}
本项目因为是课程教学项目，所以对编程语言、平台和工具都有一定的要求，所以本项目应该有以下约束：
\subsubsection{系统架构和工具}

• 编程语言: JAVA，HTML，Vue3

• 数据库：MySQL

• 使用MyBatis执行数据库事务

• 使用SpringBoot框架
\subsubsection{接口}
Orders

（1）: orders /{orderId}

•	功能：更新订单状态。

•	参数：

- orderId (String): 路径变量，表示要更新状态的订单的唯一标识符。

- orders (Orders): 请求体参数，包含订单的相关信息，如新的状态。

•	返回值：

- int: 操作的结果，通常返回影响的行数或特定的状态码。

•	描述：此接口用于在订单完成后更新其状态。例如，当用户支付订单后，可以通过此接口将订单状态更新为“已支付”，或者当订单配送完成后更新为“已完成”。该接口接收一个包含订单ID和新状态的`Orders`对象，并将订单的新状态信息更新到数据库中。操作成功后，返回影响的行数或成功的状态码；如果操作失败，返回错误码。

（2）orders/comment/{orderId}

•	功能：保存订单评论。

•	参数：orders (Orders): 一个包含订单信息的实体对象，通常包含订单ID、用户评论内容、评分等信息。

•	返回值：int: 操作的结果，通常返回影响的行数或特定的状态码。

•	描述：用户在完成订单后，可以通过此接口提交对订单的评论。该接口接收一个Orders对象，其中包含用户对订单的评分和评论内容，并将这些信息保存到数据库中。

（3） orders/comment/{orderId}

•	功能：获取特定订单的评论。

•	参数：orders (Orders): 一个包含订单信息的实体对象，用于获取特定订单的评论。

•	返回值：String: 返回特定订单的评论内容。

•	描述：此接口用于查询特定订单的用户评论。系统根据提供的Orders对象中的订单ID，从数据库中检索对应的评论信息，并将其返回给用户。

Comment

comment/{businessId}

•	功能：列出商家的所有评论。

•	参数：business (Business): 一个包含商家信息的实体对象，用于获取特定商家的所有评论。

•	返回值：List<Comment>: 一个评论列表，包含该商家所有订单的评论信息。

•	描述：用户或管理员可以通过此接口获取特定商家的所有订单评论。系统根据提供的Business对象中的商家ID，从数据库中检索所有相关的评论，并以列表形式返回。

\subsection{软件设计}
\subsubsection{数据库设计}
在原来的orders表基础上加了两个属性进行评价的展示：
\begin{table}[htbp]
  \caption{orders表补充}
  \centering
  \begin{tabular}{|c|c|c|c|}
  \hline
  No & 字段名         & 数据类型     & 说明     \\ \hline
  8  & comment        & text        & 用户评论内容     \\ \hline
  9  & payDate        & varchar     & 支付下单时间     \\ \hline
\end{tabular}
\end{table}

\subsubsection{后端设计}
后端总体设计

后端设计遵循Spring Boot框架的标准，与数据库直接连接，并通过接口与前端进行连接。后端架构主要包括以下几个层次：

1. **Po层（实体层）**：定义与数据库表对应的实体类。

2. **Mapper层（数据访问层）**：与数据库进行交互，执行SQL操作。

3. **Service层（服务层）**：包含业务逻辑，调用Mapper层的方法。

4. **Controller层（控制层）**：处理来自客户端的HTTP请求，并返回响应。

Po层设计

Po层主要负责声明后面所需要的变量，并完成所有的变量的get与set方法。以下是订单状态更新和评价功能涉及的主要变量：

(1)订单实体

- **orderId**：作为订单的唯一编号。

- **userId**：记录订单所属的用户。

- **businessId**：记录订单所属的商家。

- **orderDate**：记录订单创建的日期。

- **orderTotal**：记录订单的总金额。

- **orderState**：记录订单的状态。

- **comment**：记录用户对订单的评价。

 实体类设计示例（Orders.java）

\begin{lstlisting}[ language=xml]
  public class Orders {
    private Integer orderId;
    private String userId;
    private Integer businessId;
    private String orderDate;
    private BigDecimal orderTotal;
    private Integer orderState;
    private String comment;

    // Getters and Setters
    // ...
}
\end{lstlisting}

Controller层设计

订单Controller

Controller层处理来自客户端的HTTP请求，并调用Service层的方法来处理这些请求。使用`@RestController`和`@RequestMapping`注解来定义请求处理方法。
\begin{lstlisting}[ language=xml]
  @RestController
@RequestMapping("/orders")
public class OrdersController {
    @Autowired
    private OrdersService ordersService;

    @PutMapping("/updateStatus/{orderId}")
    public ResponseEntity<?> updateOrderStatus(@PathVariable Integer orderId, @RequestBody Orders orders) {
        int result = ordersService.updateOrderStatus(orders);
        return ResponseEntity.ok(result);
    }

    @PostMapping("/comment/{orderId}")
    public ResponseEntity<?> saveComment(@PathVariable Integer orderId, @RequestBody Orders orders) {
        int result = ordersService.saveComment(orders);
        return ResponseEntity.ok(result);
    }

    @GetMapping("/comment/{orderId}")
    public ResponseEntity<?> getComment(@PathVariable Integer orderId) {
        String comment = ordersService.getComment(orderId);
        return ResponseEntity.ok(comment);
    }
}
\end{lstlisting}

评价Controller

Controller层处理来自客户端的HTTP请求，并调用Service层的方法来处理这些请求。使用@RestController和@RequestMapping注解来定义请求处理方法。
\begin{lstlisting}[ language=xml]
  @RestController
  @RequestMapping("/comment")
  public class CommentController {
      @Autowired
      private CommentService commentService;
  
      @GetMapping("/{businessId}")
      public List<Comment> listComment(@PathVariable Integer businessId) {
          return commentService.listComment(businessId);
      }
  }
\end{lstlisting}
  
以上设计展示了订单状态更新和评价功能的后端实现。通过分层设计，实现了功能的模块化和代码的可维护性。每个层次都有明确的职责，Controller层处理HTTP请求，Service层包含业务逻辑，Mapper层与数据库进行交互，Po层定义数据模型。

\section{搜索功能}
\subsection{ 需求分析}
用户应能够在应用中搜索不同的商家、菜品或其他相关信息。搜索功能应该快速、准确，并且能够处理模糊搜索。
\subsubsection{ 功能性需求}
(1) 搜索商家：用户可以通过商家的名称或关键字搜索商家。 

(2) 搜索菜品：用户可以通过菜品名称或关键字搜索特定的菜品。 

(3) 搜索结果排序：搜索结果应该可以根据相关性或其他标准（如距离、评分）进行排序。 (4) 模糊搜索：系统应支持模糊搜索，即使用户输入的关键字不完全准确，也能返回相关的搜索结果。

(5) 搜索建议：当用户开始输入时，系统应提供搜索建议，以帮助用户快速找到他们想要的内容。 

(6) 历史搜索：系统应能够保存用户的历史搜索记录，供用户方便地重新访问。

\subsection{ 约束}
\subsubsection{系统架构和工具}
•	编程语言：JAVA，HTML，Vue3

•	数据库：MySQL

•	使用MyBatis执行数据库事务

•	使用SpringBoot框架
\subsubsection{ 接口}
businesses/search

•	参数：words（搜索关键词，类型为String）。

•	返回值：返回一个List<Business>，包含所有与搜索关键词匹配的商家信息。

•	功能：根据用户输入的搜索关键词，查询并返回与关键词相关的商家列表。

•	说明：用户可以通过输入商家名称、商品名称、商家介绍、商品介绍相关信息作为搜索关键词，系统将根据这些关键词在数据库中搜索匹配的商家记录，并返回搜索结果列表。

\subsection{ 软件设计}
\subsubsection{后端设计}
后端设计遵循Spring Boot框架的标准，与数据库直接连接，并通过接口与前端进行连接。后端架构主要包括以下几个层次：

1.	Po层（实体层）：定义与数据库表对应的实体类。

2.	Mapper层（数据访问层）：与数据库进行交互，执行SQL操作。

3.	Service层（服务层）：包含业务逻辑，调用Mapper层的方法。

4.	Controller层（控制层）：处理来自客户端的HTTP请求，并返回响应。

Po层设计

Po层主要负责声明后面所需要的变量，并完成所有的变量的get与set方法。以下是搜索功能涉及的主要变量：

•	businessName：商家的名称。

•	foodName：菜品的名称。

•	words：用户输入的搜索关键字。

Mapper层设计

Mapper层使用MyBatis技术与数据库进行连接，通过接口和注解实现SQL操作。以下是搜索功能涉及的主要方法：
listBusinessByWords：根据商家名称或关键字、商品名称或关键字搜索商家。

\begin{lstlisting}[ language=xml]
  select * from business
     	<where>
     		<foreach collection="list" item="word" separator=" OR ">
                (businessName LIKE CONCAT('%', #{word}, '%') OR businessExplain LIKE CONCAT('%', #{word}, '%'))
     		</foreach>
     		o
     		businessId in 
     		(select businessId from food
     		<where>
     			<foreach collection="list" item="word" separator=" OR ">
                	(foodName LIKE CONCAT('%', #{word}, '%') OR foodExplain LIKE CONCAT('%', #{word}, '%'))
     			</foreach>
     		</where>
     		)
     	</where>
    \end{lstlisting}

    Service层设计
    
    Service层作为业务逻辑层，调用Mapper层的方法来实现功能。使用@Service注解标识服务类，并通过@Autowired注解实现依赖注入。Term是HanLP库中用于表示分词结果的对象。
      
    \begin{lstlisting}[ language=xml]
      @Service
public class BusinessServiceImpl implements BusinessService {
	
	@Autowired
	private BusinessMapper businessMapper;

	@Override
	public List<Business> listBusinessByWords(String words) {
		List<Term> terms = StandardTokenizer.segment(words);
		List<String> wordList = new ArrayList<>();
        for (Term term : terms) {
        	wordList.add(term.word); // 将每Term对象的word属性添加到列表中
	    }
	    return businessMapper.listBusinessByWords(wordList);
	}
}
\end{lstlisting}
Controller层设计

Controller层用来实现对应的接口设计， 
负责接收来自客户端的请求并处理它们。 @RestController于标记一个类， 指示该类的方法应该将结果以JSON或XML等格式直接返回给客户端， @RequestMapping允许指定哪些HTTP请求应该由特定的Controller方法来处理，以及应该使用哪个URL路径来触发这些方法。
\begin{lstlisting}[ language=xml]
  @RestController
  @RequestMapping("/businesses")
  public class BusinessController {
    
    @Autowired
    private BusinessService businessService;
    
    @GetMapping("/search")
    public List<Business> listBusinessByWords(@RequestParam String words) {
      return businessService.listBusinessByWords(words);
    }
  }
\end{lstlisting}

\subsubsection{前端设计}

设置搜索框来提供用户搜索的接口

\begin{lstlisting}[ language=xml]
  <!-- search部分 -->
		  <div class="search">
		    <div class="search-fixed-top" ref="fixedBox">
		       <div class="search-box">
		         <i class="fa fa-search"></i>
		         <input type="text" placeholder=
             "搜索饿了么商家、商品名称"
              v-model="searchWords" @keyup.enter="performSearch">
		      </div>
		    </div>
		  </div>
     \end{lstlisting}

通过后端提供的接口对数据库中的数据进行查询：
\begin{lstlisting}[ language=xml]
  performSearch() {
	if (this.searchWords.trim().length > 0) {
	this.$router.push({ path: '/businessListForSearch',query:{searchWords:this.searchWords}});
			   }
			}
\end{lstlisting}      
